package com.example.androidawe

import android.graphics.Color
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentManager
import androidx.recyclerview.widget.ConcatAdapter
import androidx.recyclerview.widget.LinearSnapHelper
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.OnScrollListener
import kotlin.math.absoluteValue

data class PickerModel(val title: String, val level: Int)

/**
 * Created by shenhua on 2024/7/21.
 * @author shenhua
 *         Email shenhuanet@126.com
 */
class ValuePickerDialog : DialogFragment() {

    var confirmCallback: ((Int) -> Unit)? = null
    var dismissCallback: (() -> Unit)? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setStyle(STYLE_NO_TITLE, R.style.BottomDialog)
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
    ): View? {
        dialog?.window?.setGravity(Gravity.BOTTOM)
        return inflater.inflate(R.layout.dialog_value_picker, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val values = arguments?.getStringArray("values")?.toList() ?: emptyList()
        view.findViewById<TextView>(R.id.title).text = arguments?.getString("title")
        val adapter = ValueAdapter(0) {

        }
        val headerAdapter = ValueAdapter(2)
        val footerAdapter = ValueAdapter(2)
        view.findViewById<RecyclerView>(R.id.recyclerView).apply {
            this.adapter = ConcatAdapter(headerAdapter, adapter, footerAdapter)
            itemAnimator = null
        }
        adapter.submitData(values)
        view.findViewById<View>(R.id.confirm).setOnClickListener {
            dismiss()
            confirmCallback?.invoke(adapter.getPickedIndex())
        }
        view.findViewById<View>(R.id.cancel).setOnClickListener {
            dismiss()
        }
    }
}

private class ValueAdapter(
    private val appendCount: Int = 0, private val callback: ((Int) -> Unit)? = null
) : RecyclerView.Adapter<ValueAdapter.ViewHolder>() {

    private val mData = mutableListOf<PickerModel>()
    private var mPickedIndex = 0

    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val titleView: TextView = itemView.findViewById(R.id.tv)
    }

    override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
        super.onAttachedToRecyclerView(recyclerView)
        if (callback == null) return
        val snapHelper = LinearSnapHelper()
        snapHelper.attachToRecyclerView(recyclerView)
        recyclerView.addOnScrollListener(object : OnScrollListener() {
            override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                super.onScrollStateChanged(recyclerView, newState)
                if (RecyclerView.SCROLL_STATE_IDLE == newState) {
                    snapHelper.findSnapView(recyclerView.layoutManager)?.let {
                        val position = recyclerView.getChildAdapterPosition(it) - 2
                        callback.invoke(position)
                        if (position != mPickedIndex) {
                            mPickedIndex = position
                            notifyItemRangeChanged(0, itemCount)
                        }
                    }
                }
            }
        })
    }

    fun submitData(list: List<String>, defaultIndex: Int = 0) {
        mData.clear()
        mData.addAll(
            list.withIndex().map { PickerModel(it.value, if (defaultIndex == it.index) 1 else 0) })
        notifyItemRangeInserted(0, list.size)
    }

    fun getPickedIndex() = mPickedIndex

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val itemView =
            LayoutInflater.from(parent.context).inflate(R.layout.item_value_picker, parent, false)
        return ViewHolder(itemView)
    }

    override fun getItemCount() = if (appendCount == 0) mData.size else appendCount

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        if (appendCount == 0) {
            val item = mData[position]
            holder.titleView.text = item.title
            val colorRes = when ((position - mPickedIndex).absoluteValue) {
                0 -> android.R.color.black
                1 -> android.R.color.holo_blue_dark
                else -> android.R.color.holo_purple
            }
            holder.titleView.setTextColor(ContextCompat.getColor(holder.itemView.context, colorRes))
        }
    }
}

class ValuePickerBuilder {
    private var title: String = "标题"
    private var values: Array<String> = arrayOf()
    private var confirmCallback: ((Int) -> Unit)? = null
    private var dismissCallback: (() -> Unit)? = null
    fun title(title: String): ValuePickerBuilder {
        this.title = title
        return this
    }

    fun values(array: Array<String>): ValuePickerBuilder {
        this.values = array
        return this
    }

    fun confirm(callback: ((Int) -> Unit)): ValuePickerBuilder {
        this.confirmCallback = callback
        return this
    }

    fun dismiss(callback: () -> Unit): ValuePickerBuilder {
        this.dismissCallback = callback
        return this
    }

    fun build(): ValuePickerBuilder {
        return this
    }

    fun showDialog(fragmentManager: FragmentManager) {
        ValuePickerDialog().apply {
            arguments = bundleOf("title" to title, "values" to values)
            confirmCallback = this@ValuePickerBuilder.confirmCallback
            dismissCallback = this@ValuePickerBuilder.dismissCallback
        }.show(fragmentManager, "ValuePickerDialog")
    }
}